using Microsoft.EntityFrameworkCore;
using Mark.Models;
using MarkFileInfo = Mark.Models.FileInfo;

namespace Mark.Data;

/// <summary>
/// Mark应用程序数据库上下文
/// </summary>
public class MarkDbContext : DbContext
{
    public MarkDbContext(DbContextOptions<MarkDbContext> options) : base(options)
    {
    }

    // DbSet 属性
    public DbSet<User> Users { get; set; }
    public DbSet<Provider> Providers { get; set; }
    public DbSet<Model> Models { get; set; }
    public DbSet<Conversation> Conversations { get; set; }
    public DbSet<Message> Messages { get; set; }
    public DbSet<MarkFileInfo> FileInfos { get; set; }
    public DbSet<MessageFile> MessageFiles { get; set; }
    public DbSet<SystemSettings> SystemSettings { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 用户配置
        modelBuilder.Entity<User>(entity =>
        {
            entity.HasIndex(e => e.Username).IsUnique();
            entity.HasIndex(e => e.Email).IsUnique();
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
        });

        // 提供商配置
        modelBuilder.Entity<Provider>(entity =>
        {
            entity.HasIndex(e => e.Name).IsUnique();
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
        });

        // 模型配置
        modelBuilder.Entity<Model>(entity =>
        {
            entity.HasIndex(e => new { e.ProviderId, e.Name }).IsUnique();
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
            
            entity.HasOne(d => d.Provider)
                .WithMany(p => p.Models)
                .HasForeignKey(d => d.ProviderId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        // 对话配置
        modelBuilder.Entity<Conversation>(entity =>
        {
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.LastActivityAt).HasDefaultValueSql("datetime('now')");
            
            entity.HasOne(d => d.User)
                .WithMany(p => p.Conversations)
                .HasForeignKey(d => d.UserId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        // 消息配置
        modelBuilder.Entity<Message>(entity =>
        {
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
            
            entity.HasOne(d => d.Conversation)
                .WithMany(p => p.Messages)
                .HasForeignKey(d => d.ConversationId)
                .OnDelete(DeleteBehavior.Cascade);
                
            entity.HasOne(d => d.Model)
                .WithMany(p => p.Messages)
                .HasForeignKey(d => d.ModelId)
                .OnDelete(DeleteBehavior.SetNull);
                
            entity.HasOne(d => d.ParentMessage)
                .WithMany(p => p.ChildMessages)
                .HasForeignKey(d => d.ParentMessageId)
                .OnDelete(DeleteBehavior.Restrict);
        });

        // 文件信息配置
        modelBuilder.Entity<MarkFileInfo>(entity =>
        {
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.LastModified).HasDefaultValueSql("datetime('now')");
            
            entity.HasOne(d => d.User)
                .WithMany(p => p.Files)
                .HasForeignKey(d => d.UserId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        // 消息文件关联配置
        modelBuilder.Entity<MessageFile>(entity =>
        {
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
            
            entity.HasOne(d => d.Message)
                .WithMany(p => p.MessageFiles)
                .HasForeignKey(d => d.MessageId)
                .OnDelete(DeleteBehavior.Cascade);
                
            entity.HasOne(d => d.FileInfo)
                .WithMany(p => p.MessageFiles)
                .HasForeignKey(d => d.FileInfoId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        // 系统设置配置
        modelBuilder.Entity<SystemSettings>(entity =>
        {
            entity.HasIndex(e => e.Key).IsUnique();
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");
        });
    }

    public override int SaveChanges()
    {
        UpdateTimestamps();
        return base.SaveChanges();
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        UpdateTimestamps();
        return await base.SaveChangesAsync(cancellationToken);
    }

    private void UpdateTimestamps()
    {
        var entries = ChangeTracker.Entries()
            .Where(e => e.Entity is BaseEntity && (e.State == EntityState.Added || e.State == EntityState.Modified));

        foreach (var entityEntry in entries)
        {
            if (entityEntry.Entity is BaseEntity entity)
            {
                if (entityEntry.State == EntityState.Added)
                {
                    entity.CreatedAt = DateTime.UtcNow;
                }
                entity.UpdatedAt = DateTime.UtcNow;
            }
        }
    }
} 